package repository

import (
	"context"
	"elegantGo/chapter17/oo"
	"elegantGo/chapter17/repository/ent"
	"elegantGo/chapter17/repository/ent/article"
)

type Article struct {
	db *ent.Client
}

func NewArticle(db *ent.Client) *Article {
	repo := new(Article)
	repo.db = db
	return repo
}

func (repo *Article) Fetch(ctx context.Context, id int) oo.Article {
	return repo.FetchOne(ctx, func(opt *ent.ArticleQuery) {
		opt.Where(article.ID(id))
	})
}

func (repo *Article) FetchOne(ctx context.Context, optionFunc func(query *ent.ArticleQuery)) oo.Article {
	builder := repo.db.Article.Query()
	optionFunc(builder)
	return builder.FirstX(ctx).Mapper()
}

func (repo *Article) FetchMany(ctx context.Context, optionFunc func(query *ent.ArticleQuery)) oo.Articles {
	builder := repo.db.Article.Query()
	optionFunc(builder)
	var entArticles ent.Articles = builder.AllX(ctx)
	return entArticles.Mapper()
}

func (repo *Article) Save(ctx context.Context, ooArticle oo.Article) oo.Article {
	builder := repo.db.Article.Create().
		SetCategory(ooArticle.GetCategory()).
		SetTitle(ooArticle.GetTitle()).
		SetContent(ooArticle.GetContent())

	if payPerArticle, ok := ooArticle.(*oo.PaidArticle); ok {
		builder.SetPrice(payPerArticle.GetPrice())
		builder.SetSaleCount(payPerArticle.GetSaleCount())
	}

	return builder.SaveX(ctx).Mapper()
}
